﻿using System;
using System.Collections.Generic;
using System.Text;
using T.FAS.Runtime.Metadata.Entity.Page;
using T.ServiceComponent.DAC.Service;
using System.Data;
using System.Reflection;
using System.Linq;

namespace T.FAS.Runtime.Page.Dao
{
    class MenuDao : DaoService<FasMenu>
    {
        public override string TableName => "FAS_Menu";
        public override string IDColumnName => "ID";

        public override string DBName => "TFAS";

        public override List<string> ExceptColumnName => new List<string>() { "MetaDataID", "MetaDataCode", "MetaDataName","KeyApplicationName",
            "CurrentVersion", "CompatibleMinVersion","EngineVersion","MetaData","PageProjectID","PageBranchID","PageBranchName","ProjectBranchID","TranslatedTerms" ,"Disabled","PageMetaData","MenuImage","MenuUrlParams" };

        public List<string> ExceptColumnNameForUpdate => new List<string>() { "ID", "Creator", "CreateTime" };

        private  List<string> columnsForSQL;
        private  List<string> ColumnsForSQL
        {
            get
            {
                if (columnsForSQL == null)
                {
                    columnsForSQL = Columns.Keys.ToList();
                    foreach (string item in ExceptColumnName)
                    {
                        columnsForSQL.Remove(item);
                    }
                }
                return columnsForSQL;
            }
        }

        public void Add(FasMenu data)
        {
            string format = "insert into {0} ({1}) values ({2})";
            StringBuilder stringBuilder = null;
            StringBuilder stringBuilder2 = new StringBuilder(100);
            int num = 0;
         
            foreach (string item2 in ColumnsForSQL)
            {
                if (stringBuilder == null)
                {
                    stringBuilder = new StringBuilder(100);
                    stringBuilder.Append(item2);
                    stringBuilder2.Append(":param" + num);
                }
                else
                {
                    stringBuilder.Append("," + item2);
                    stringBuilder2.Append(",:param" + num);
                }

                num++;
            }

            format = string.Format(format, TableName, stringBuilder.ToString(), stringBuilder2.ToString());

            Dictionary<string, object> dataMapping = GetDataMapping(data);

            List<object> paramter = GetParamter(ColumnsForSQL, dataMapping);
            DB.ExecSqlStatement(format, paramter.ToArray());
        }

        public void Update(FasMenu data)
        {
            if (data == null)
            {
                return;
            }

            string format = "update {0} set {1} where {2}";
            StringBuilder stringBuilder = null;
            int num = 0;
           var columns = ColumnsForSQL.ToList();

            foreach (string item in ExceptColumnNameForUpdate)
            {
                columns.Remove(item);
            }

            foreach (string col in columns)
            {
                if (stringBuilder == null)
                {
                    stringBuilder = new StringBuilder(100);
                    stringBuilder.Append(col + "=:param" + num);
                }
                else
                {
                    stringBuilder.Append("," + col + "=:param" + num);
                }

                num++;
            }

            format = string.Format(format, TableName, stringBuilder.ToString(), IDColumnName + "=:param" + num);

            Dictionary<string, object> dataMapping = GetDataMapping(data);
            List<object> paramter = GetParamter(columns, dataMapping);
            paramter.Add(dataMapping[IDColumnName]);

            DB.ExecSqlStatement(format, paramter.ToArray());
        }


        private List<object> GetParamter(List<string> keys, Dictionary<string, object> values)
        {
            List<object> list = new List<object>();
            foreach (string key in keys)
            {
                list.Add(values[key]);
            }

            return list;
        }

        public int Delete(string id)
        {
            string sql = $"delete from {TableName} where ID=@ID ";
            var paramId = DB.MakeInParam("@ID", T.ServiceComponent.DataAccessEx.Core.TDbDataType.VarChar, id);
            return DB.ExecSqlStatement(sql, paramId);
        }


        public override Dictionary<string, object> GetDataMapping(FasMenu data)
        {
            if (base.Columns == null)
            {
                return null;
            }

            Dictionary<string, object> dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            foreach (string key in base.Columns.Keys)
            {
                PropertyInfo propertyInfo = base.Columns[key];
                if (!dictionary.ContainsKey(propertyInfo.Name) && propertyInfo.ReflectedType == data.GetType())
                {
                    if (propertyInfo.PropertyType == typeof(bool))
                    {
                        bool flag = Convert.ToBoolean(propertyInfo.GetValue(data));
                        dictionary.Add(propertyInfo.Name, flag ? "1" : "0");
                    }
                    else
                    {
                        dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(data));
                    }
                }
            }

            return dictionary;
        }

        public override FasMenu ConvertToObject(Dictionary<string, PropertyInfo> columns, DataRow row)
        {
            Dictionary<string, PropertyInfo> myCol = new Dictionary<string, PropertyInfo>(columns);
            foreach (var item in ExceptColumnName)
            {
                myCol.Remove(item);
            }
            var data = GetObject(row, myCol);

            if (Mapping != null)
            {
                foreach (var item in Mapping.Keys)
                {
                    PropertyInfo pi = typeof(FasMenu).GetProperty(item, BindingFlags.Public | BindingFlags.Instance);

                    var tDatas = Mapping[item].GetByForeignKey(Convert.ToString(row[IDColumnName]));
                    SetProperty(data, pi, tDatas);
                }
            }

            return data;
        }


        private static FasMenu GetObject(DataRow row, Dictionary<string, PropertyInfo> columns)
        {
            if (row == null || columns == null)
                return default(FasMenu);
            FasMenu data = new FasMenu();

            foreach (var item in columns.Keys)
            {
                var dtype = columns[item];
                if (dtype.PropertyType == typeof(bool))
                {
                    var dataT = Convert.ToString(row[item]);
                    if (dataT == "1")
                        dtype.SetValue(data, true);
                    else
                        dtype.SetValue(data, false);
                }
                else
                    dtype.SetValue(data, Convert.ChangeType(row[item], dtype.PropertyType));
            }

            return data;
        }
    }
}
